/**************************************************************************************************

    Phyplus Microelectronics Limited confidential and proprietary.
    All rights reserved.

    IMPORTANT: All rights of this software belong to Phyplus Microelectronics
    Limited ("Phyplus"). Your use of this Software is limited to those
    specific rights granted under  the terms of the business contract, the
    confidential agreement, the non-disclosure agreement and any other forms
    of agreements as a customer or a partner of Phyplus. You may not use this
    Software unless you agree to abide by the terms of these agreements.
    You acknowledge that the Software may not be modified, copied,
    distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy
    (BLE) integrated circuit, either as a product or is integrated into your
    products.  Other than for the aforementioned purposes, you may not use,
    reproduce, copy, prepare derivative works of, modify, distribute, perform,
    display or sell this Software and/or its documentation for any purposes.

    YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
    PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
    INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
    NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
    PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT,
    NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
    LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
    INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
    OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
    OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
    (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.

**************************************************************************************************/

/**************************************************************************************************
    Filename:       simpleBLEPeripheral.c
    Revised:
    Revision:

    Description:    This file contains the Simple BLE Peripheral sample application


**************************************************************************************************/
/*********************************************************************
    INCLUDES
*/
#include <string.h>
#include "bcomdef.h"
#include "rf_phy_driver.h"
#include "global_config.h"
#include "OSAL.h"
#include "OSAL_PwrMgr.h"
#include "gatt.h"
#include "hci.h"
#include "gapgattserver.h"
#include "gattservapp.h"
//#include "devinfoservice.h"
#include "sbpProfile_ota.h"

#ifdef PHY_OTA_ENABLE
    #include "ota_app_service.h"
#endif
#include "peripheral.h"
#include "gapbondmgr.h"
#include "pwrmgr.h"
#include "gpio.h"
#include "simpleBLEPeripheral.h"
#include "ll.h"
#include "ll_hw_drv.h"
#include "ll_def.h"
#include "hci_tl.h"
#include "l2cap_internal.h"

#include "bleuart_service.h"
#include "adc.h"

#include "gatt.h"
#include "gatt_uuid.h"
/*********************************************************************
    MACROS
*/
//#define LOG(...)
/*********************************************************************
    CONSTANTS
*/

// How often to perform periodic event
#define SBP_PERIODIC_EVT_PERIOD                   5000
#define SBP_PPSP_PERIODIC_EVT_PERIOD              500

#define DEVINFO_SYSTEM_ID_LEN                     8
#define DEVINFO_SYSTEM_ID                         0


#define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL

// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL     800//24//32//80

// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800//48//800

// Slave latency to use if automatic parameter update request is enabled
#define DEFAULT_DESIRED_SLAVE_LATENCY         0

// Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_CONN_TIMEOUT          400//1000

// Whether to enable automatic parameter update request when a connection is formed
#define DEFAULT_ENABLE_UPDATE_REQUEST         TRUE//FALSE

// Connection Pause Peripheral time value (in seconds)
#define DEFAULT_CONN_PAUSE_PERIPHERAL         6

#define INVALID_CONNHANDLE                    0xFFFF

// Default passcode
#define DEFAULT_PASSCODE                      0//19655

// Length of bd addr as a string
#define B_ADDR_STR_LEN                        15

#define RESOLVING_LIST_ENTRY_NUM              10


/*********************************************************************
    build define
*/

#define APP_CFG_RPA_TEST                       0

#define DBG_RTC_TEST                           0

#define LATENCY_TEST                           0

#define DYNAMIC_CLK_CHG_TEST                   0

/*********************************************************************
    TYPEDEFS
*/

/*********************************************************************
    GLOBAL VARIABLES
*/
perStatsByChan_t g_perStatsByChanTest;

/*********************************************************************
    EXTERNAL VARIABLES
*/
volatile uint8_t g_current_advType = LL_ADV_CONNECTABLE_UNDIRECTED_EVT;

//extern wtnrTest_t wtnrTest;
extern l2capSARDbugCnt_t g_sarDbgCnt;
extern uint32 g_osal_mem_allo_cnt;
extern uint32 g_osal_mem_free_cnt;

extern uint32 counter_tracking;

extern uint32 g_counter_traking_avg;
extern uint32 g_counter_traking_cnt;
extern uint32_t  g_TIM2_IRQ_TIM3_CurrCount;
extern uint32_t  g_TIM2_IRQ_to_Sleep_DeltTick;
extern uint32_t  g_osal_tick_trim;
extern uint32_t  g_TIM2_IRQ_PendingTick;
extern uint32_t  g_TIM2_wakeup_delay;

/*********************************************************************
    EXTERNAL FUNCTIONS
*/


/*********************************************************************
    LOCAL VARIABLES
*/
static uint8 simpleBLEPeripheral_TaskID;   // Task ID for internal task/event processing

static gaprole_States_t gapProfileState = GAPROLE_INIT;

uint16 gapConnHandle = INVALID_CONNHANDLE;
attHandleValueNoti_t notify_data= {0};


// advert data for iBeacon
static uint8 advertData[] =
{
	  0x03,
	  GAP_ADTYPE_APPEARANCE,
	  0x40,
	  0x02,
    0x02,   // length of this data
    GAP_ADTYPE_FLAGS,
    DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
	  0x09,
	  GAP_ADTYPE_16BIT_COMPLETE,
	  0xf1,0xff,0x02,0x18,0x04,0x18,0x03,0x18,
	  
    0x0d,   // length of this data
    GAP_ADTYPE_LOCAL_NAME_COMPLETE,
		'H',
		'P',
		'T',
		'1',
		'0',
		'2',
		'B',
		'_',
		'V',
		'1',
		'.',
		'2',

};





// GAP GATT Attributes
static uint8 attDeviceName[GAP_DEVICE_NAME_LEN] = "Body Temp_6222 ";
/*********************************************************************
    LOCAL FUNCTIONS
*/
static void peripheralStateNotificationCB( gaprole_States_t newState );
static void peripheralStateReadRssiCB( int8 rssi  );

bStatus_t smp_notify_data(uint8_t n_size, uint8_t* n_data);

/*********************************************************************
    PROFILE CALLBACKS
*/

// GAP Role Callbacks
static gapRolesCBs_t simpleBLEPeripheral_PeripheralCBs =
{
    peripheralStateNotificationCB,  // Profile State Change Callbacks
    peripheralStateReadRssiCB       // When a valid RSSI is read from controller (not used by application)
};
#if (DEF_GAPBOND_MGR_ENABLE==1)
//GAP Bond Manager Callbacks, add 2017-11-15
static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
{
    NULL,                     // Passcode callback (not used by application)
    NULL                      // Pairing / Bonding state Callback (not used by application)
};
#endif


/*********************************************************************
    PUBLIC FUNCTIONS
*/

/*
    channel:
    is_differential_mode:
    is_high_resolution:
    [bit7~bit2]=[p20,p15~p11],ignore[bit1,bit0]
    when measure adc(not battery),we'd better use high_resolution.
    when measure battery,we'd better use no high_resolution and keep the gpio alone.

    differential_mode is rarely used,
    if use please config channel as one of [ADC_CH3DIFF,ADC_CH2DIFF,ADC_CH1DIFF],
    and is_high_resolution as one of [0x80,0x20,0x08],
    then the pair of [P20~P15,P14~P13,P12~P11] will work.
    other adc channel cannot work.
*/
static adc_Cfg_t adc_cfg =
{

//    .channel = ADC_BIT(ADC_CH3P_P20)| ADC_BIT(ADC_CH3N_P15) | ADC_BIT(ADC_CH2P_P14),
//	  .channel              = ADC_BIT(ADC_CH1P_P23),//ADC_BIT(ADC_CH2N_P24),//ADC_BIT(ADC_CH3N_P15),//ADC_BIT(ADC_CH1N_P11),//ADC_BIT(ADC_CH1P_P23),
    .channel              = ADC_BIT(ADC_CH2N_P24)| ADC_BIT(ADC_CH3N_P15) | ADC_BIT(ADC_CH1N_P11) | ADC_BIT(ADC_CH1P_P23),
//	  .channel              =  ADC_BIT(ADC_CH0DIFF)| ADC_BIT(ADC_CH1DIFF) | ADC_BIT(ADC_CH3DIFF),
	  .is_continue_mode     = FALSE,
    .is_differential_mode = 0x00,
    .is_high_resolution   = 0xff,//0x00,

};


static void adc_evt(adc_Evt_t* pev)
{
}

static void adc_MeasureTask( void )
{
	  static uint8_t stop = 0;
	  uint16_t adcs_P11[8];
	  uint16_t adcs_P23[8];
	  uint16_t adcs_P24[8];
	  uint16_t adcs_P15[8];
	  uint8_t  size = 8;
    int ret;

    ret = hal_adc_config_channel(adc_cfg,adc_evt);

    if(ret)
    {
        LOG("ret = %d\n",ret);
        return;
    }
    
		
    hal_adc_start(POLLING_MODE);
    
		{
			uint32_t sum_P11,sum_P23,sum_P24,sum_P15;;
			
			for(uint8_t i=0; i<size; i++)
			{
//				adcs[i] = hal_adc_value_read(ADC_CH1P_P23);
//        adcs[i] = hal_adc_value_read(ADC_CH1N_P11);
//				adcs[i] = hal_adc_value_read(ADC_CH2N_P24);
//				adcs[i] = hal_adc_value_read(ADC_CH3N_P15);
				
				adcs_P11[i] = hal_adc_value_read(ADC_CH1N_P11);
				adcs_P23[i] = hal_adc_value_read(ADC_CH1P_P23);
				adcs_P24[i] = hal_adc_value_read(ADC_CH2N_P24);
				adcs_P15[i] = hal_adc_value_read(ADC_CH3N_P15);
				
				AP_PCRM->ANA_CTL &= ~BIT(3);
				AP_PCRM->ANA_CTL &= ~BIT(0);
//				WaitMs(1);
				AP_PCRM->ANA_CTL |= BIT(0);
//				WaitMs(10);
				AP_PCRM->ANA_CTL |= BIT(3);
				
//				hal_poilling_adc_stop();
//		    WaitMs(100);
			}
			sum_P11 = 0;
			sum_P23 = 0;
			sum_P24 = 0;
			sum_P15 = 0;
			for(uint8_t i=0;i<size;i++)
			{
				sum_P11 += adcs_P11[i];
				sum_P23 += adcs_P23[i];
				sum_P24 += adcs_P24[i];
				sum_P15 += adcs_P15[i];
			}
			sum_P11 /=size;
			sum_P23 /=size;
			sum_P24 /=size;
			sum_P15 /=size;

			{
				uint32_t r2;
				uint32_t r1=300000;//OMiGa
				uint32_t vcc=33000;//33000;//mV
				uint32_t vol_r2;   // = value *100000;
				
				bool is_high_resolution = TRUE;
        bool is_differential_mode = FALSE;
				volatile float value_P11,value_P23,value_P24,value_P15;
				value_P11= hal_adc_value_cal(ADC_CH1N_P11,adcs_P11, size, is_high_resolution,is_differential_mode);
				value_P23= hal_adc_value_cal(ADC_CH1P_P23,adcs_P23, size, is_high_resolution,is_differential_mode);
				value_P24= hal_adc_value_cal(ADC_CH2N_P24,adcs_P24, size, is_high_resolution,is_differential_mode);
				value_P15= hal_adc_value_cal(ADC_CH3N_P15,adcs_P15, size, is_high_resolution,is_differential_mode);
				
//				LOG("Vol %d\n",(int)(value*10000));
				LOG("%d %d %d %d\n",(int)(value_P11*10000),(int)(value_P23*10000),(int)(value_P24*10000),(int)(value_P15*10000));
				
				vol_r2 = value_P11 *10000;				
				r2 = vol_r2 * r1;
				r2 /= (vcc-vol_r2);
				
//				LOG("%d\n",r2);
				
				{
					uint8_t size;
					uint8_t r_data[2];
				  if(gapConnHandle != INVALID_CONNHANDLE)
				  {
						r_data[0] = r2 >> 8;
						r_data[1] = r2;
					  smp_notify_data(2, r_data);
				  }
					
				}
				
				{
					static uint16_t i=0;
					
					if(i < 150)
					{
						i++;
					}
					else
					{
						i=0;
						LOG("99999\n");
						stop = 1;
					}
				}
			}
		}
		
    hal_poilling_adc_stop();
		if(stop == 0)
    osal_start_timerEx(simpleBLEPeripheral_TaskID, SBP_OSAL_EVT_ADC_TASK,2000);
}

/*
static void adc_MeasureTask( void )
{
	  static uint8_t stop = 0;
	  uint16_t adcs_P18[8];
	  uint16_t adcs_P23[8];
	  uint16_t adcs_P14[8];
	  uint16_t adcs_P20[8];
	  uint8_t  size = 8;
    int ret;
	
		for(uint8_t chn=1;chn<4;chn++)
		{
			//setup for diff sampleing channel 
			if(chn == 0)
			{
				adc_cfg.channel = ADC_BIT(ADC_CH0DIFF);
				adc_cfg.is_differential_mode = 0x02;
				ret = hal_adc_config_channel(adc_cfg,adc_evt);

				if(ret)
				{
						LOG("ret = %d\n",ret);
						return;
				}
			}
			else if(chn == 1)
			{
				adc_cfg.channel = ADC_BIT(ADC_CH1DIFF);
				adc_cfg.is_differential_mode = 0x08;
				ret = hal_adc_config_channel(adc_cfg,adc_evt);

				if(ret)
				{
						LOG("ret = %d\n",ret);
						return;
				}
			}
			else if(chn == 2)
			{
				adc_cfg.channel = ADC_BIT(ADC_CH2DIFF);
				adc_cfg.is_differential_mode = 0x20;
				ret = hal_adc_config_channel(adc_cfg,adc_evt);

				if(ret)
				{
						LOG("ret = %d\n",ret);
						return;
				}
			}
			else if(chn == 3)
			{
				adc_cfg.channel = ADC_BIT(ADC_CH3DIFF);
				adc_cfg.is_differential_mode = 0x80;
				ret = hal_adc_config_channel(adc_cfg,adc_evt);

				if(ret)
				{
						LOG("ret = %d\n",ret);
						return;
				}
			}
			
			 hal_adc_start(POLLING_MODE);
				
			
			for(uint8_t i=0; i<size; i++)
			{

				if(chn ==0)
				{
					adcs_P18[i] = hal_adc_value_read(ADC_CH0DIFF);
				}
				else if(chn ==1)
				{
					adcs_P23[i] = hal_adc_value_read(ADC_CH1DIFF);
				}
				else if(chn ==2)
				{
					adcs_P14[i] = hal_adc_value_read(ADC_CH2DIFF);
				}
				else if(chn ==3)
				{
					adcs_P20[i] = hal_adc_value_read(ADC_CH3DIFF);
				}
				

				
				AP_PCRM->ANA_CTL &= ~BIT(3);
				AP_PCRM->ANA_CTL &= ~BIT(0);
		//				WaitMs(1);
				AP_PCRM->ANA_CTL |= BIT(0);
		//				WaitMs(10);
				AP_PCRM->ANA_CTL |= BIT(3);
				
		//				hal_poilling_adc_stop();
		//		    WaitMs(100);
			}
			
			hal_poilling_adc_stop();
			
		}
    
		

			
		{
	//			uint32_t sum_P18,sum_P23,sum_P14,sum_P20;;
	//			
	//			
	//			sum_P18 = 0;
	//			sum_P23 = 0;
	//			sum_P14 = 0;
	//			sum_P20 = 0;
	//			for(uint8_t i=0;i<size;i++)
	//			{
	//				sum_P18 += adcs_P18[i];
	//				sum_P23 += adcs_P23[i];
	//				sum_P14 += adcs_P14[i];
	//				sum_P20 += adcs_P20[i];
	//			}
	//			sum_P18 /=size;
	//			sum_P23 /=size;
	//			sum_P14 /=size;
	//			sum_P20 /=size;

			{
				
				
				bool is_high_resolution = TRUE;
				bool is_differential_mode = TRUE;
				volatile float value_P18,value_P23,value_P14,value_P20;
				value_P18= hal_adc_value_cal(ADC_CH0DIFF,adcs_P18, size, is_high_resolution,is_differential_mode);
				value_P23= hal_adc_value_cal(ADC_CH1DIFF,adcs_P23, size, is_high_resolution,is_differential_mode);
				value_P14= hal_adc_value_cal(ADC_CH2DIFF,adcs_P14, size, is_high_resolution,is_differential_mode);
				value_P20= hal_adc_value_cal(ADC_CH3DIFF,adcs_P20, size, is_high_resolution,is_differential_mode);
				

				LOG("%d %d %d %d\n",(int)(value_P18*10000),(int)(value_P23*10000),(int)(value_P14*10000),(int)(value_P20*10000));
				
			
				
				{
					uint8_t size;
					uint8_t r_data[2];
					if(gapConnHandle != INVALID_CONNHANDLE)
					{
						r_data[0] = 0x11;
						r_data[1] = 0x22;
						smp_notify_data(2, r_data);
					}
					
				}
				
				{
					static uint16_t i=0;
					
					if(i < 150)
					{
						i++;
					}
					else
					{
						i=0;
						LOG("99999\n");
						stop = 1;
					}
				}
			}
		}
		

		if(stop == 0)
    osal_start_timerEx(simpleBLEPeripheral_TaskID, SBP_OSAL_EVT_ADC_TASK,2000);
}
*/




bStatus_t smp_notify_data(uint8_t n_size, uint8_t* n_data)
{
    if(n_size > ATT_MTU_SIZE-3)
        notify_data.len = ATT_MTU_SIZE-3;
    else
        notify_data.len = n_size;

    memcpy(notify_data.value, n_data, notify_data.len);
    return bleuart_Notify( gapConnHandle, &notify_data, simpleBLEPeripheral_TaskID );
}


void on_bleuartServiceEvt(bleuart_Evt_t* pev)
{
    switch(pev->ev)
    {
    case bleuart_EVT_TX_NOTI_DISABLED:
        //BUP_disconnect_handler();
        osal_set_event(simpleBLEPeripheral_TaskID,SBP_OSAL_EVT_NOTIFY_DISABLE);
        break;

    case bleuart_EVT_TX_NOTI_ENABLED :
        //BUP_connect_handler();
        osal_set_event(simpleBLEPeripheral_TaskID,SBP_OSAL_EVT_NOTIFY_ENABLE);
        break;

    case bleuart_EVT_BLE_DATA_RECIEVED:
			  LOG("123456\n");
        break;

    default:
        break;
    }
}


/*********************************************************************
    @fn      SimpleBLEPeripheral_Init

    @brief   Initialization function for the Simple BLE Peripheral App Task.
            This is called during initialization and should contain
            any application specific initialization (ie. hardware
            initialization/setup, table initialization, power up
            notificaiton ... ).

    @param   task_id - the ID assigned by OSAL.  This ID should be
                      used to send messages and set timers.

    @return  none
*/
#define EMPTY_UUID_1                        0xFFE0
#define EMPTY_UUID_2                        0XFFE1
#define EMPTY_UUID_3                        0xFFE2
//1
uint8 empty1_ServiceUUID[ATT_BT_UUID_SIZE] =
{
    LO_UINT16(EMPTY_UUID_1), HI_UINT16(EMPTY_UUID_1)
};
static gattAttrType_t empty1_Service = { ATT_BT_UUID_SIZE, empty1_ServiceUUID };
//
gattAttribute_t empty1_ProfileAttrTbl[] =
{
    // Simple Profile Service
    {
        { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
        GATT_PERMIT_READ,                         /* permissions */
        0,                                        /* handle */
        (uint8*)& empty1_Service                  /* pValue */
    },
};
//2
uint8 empty2_ServiceUUID[ATT_BT_UUID_SIZE] =
{
    LO_UINT16(EMPTY_UUID_2), HI_UINT16(EMPTY_UUID_2)
};
static gattAttrType_t empty2_Service = { ATT_BT_UUID_SIZE, empty2_ServiceUUID };

#define  E2SC1_UUID   0xffe5
uint8 e2sc1_charUUID[ATT_BT_UUID_SIZE] =
{
    LO_UINT16(E2SC1_UUID), HI_UINT16(E2SC1_UUID)
};
uint8 e2sc1_CharValue[6];
//
uint8 e2sc1_CharProps = GATT_PROP_READ;
gattAttribute_t empty2_ProfileAttrTbl[] =
{
    // Simple Profile Service
    {
        { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
        GATT_PERMIT_READ,                         /* permissions */
        0,                                        /* handle */
        (uint8*)& empty2_Service                  /* pValue */
    },
		
//		 // Characteristic 1 Declaration
//    {
//        { ATT_BT_UUID_SIZE, characterUUID },
//        GATT_PERMIT_READ,
//        0,
//        &e2sc1_CharProps
//    },

//    // Characteristic Value 1
//    {
//        { ATT_BT_UUID_SIZE, e2sc1_charUUID },
//        GATT_PERMIT_WRITE,
//        0,
//        &e2sc1_CharValue[0]
//    },
};



void SimpleBLEPeripheral_Init( uint8 task_id )
{
    simpleBLEPeripheral_TaskID = task_id;
   
    // Setup the GAP
    VOID GAP_SetParamValue( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL );
    // Setup the GAP Peripheral Role Profile
    {
        // device starts advertising upon initialization
        uint8 initial_advertising_enable = TRUE;
        uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST;
        uint8 advChnMap = GAP_ADVCHAN_37 | GAP_ADVCHAN_38 | GAP_ADVCHAN_39;
        // By setting this to zero, the device will go into the waiting state after
        // being discoverable for 30.72 second, and will not being advertising again
        // until the enabler is set back to TRUE
        uint16 gapRole_AdvertOffTime = 0;
        uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
        uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
        uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY;
        uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT;
        uint8 peerPublicAddr[] =
        {
            0x01,
            0x02,
            0x03,
            0x04,
            0x05,
            0x06
        };
        uint8 advType =g_current_advType;// LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT;//LL_ADV_SCANNABLE_UNDIRECTED_EVT;//LL_ADV_CONNECTABLE_LDC_DIRECTED_EVT;//;    // it seems a  bug to set GAP_ADTYPE_ADV_NONCONN_IND = 0x03
        GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof( uint8 ), &advType );
        GAPRole_SetParameter(GAPROLE_ADV_DIRECT_ADDR, sizeof(peerPublicAddr), peerPublicAddr);
        // set adv channel map
        GAPRole_SetParameter(GAPROLE_ADV_CHANNEL_MAP, sizeof(uint8), &advChnMap);
        // Set the GAP Role Parameters
        GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
        GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );

        GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
        GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request );
        GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval );
        GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval );
        GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency );
        GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout );
    }
    // Set the GAP Characteristics
    GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName );
    // Set advertising interval
    {
        uint16 advInt = 160;//800;//2400;//1600;//1600;//800;//1600;   // actual time = advInt * 625us
        GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, advInt );
        GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, advInt );
        GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, advInt );
        GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, advInt );
    }
    #if(DEF_GAPBOND_MGR_ENABLE==1)
    // Setup the GAP Bond Manager
    {
        uint32 passkey = DEFAULT_PASSCODE;
        uint8 pairMode = GAPBOND_PAIRING_MODE_INITIATE ;//GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
        uint8 mitm = TRUE;
        uint8 ioCap = GAPBOND_IO_CAP_NO_INPUT_NO_OUTPUT;
        uint8 bonding = TRUE;
        GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey );
        GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode );
        GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm );
        GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap );
        GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding );
    }
    #endif
    // Initialize GATT attributes
    GGS_AddService( GATT_ALL_SERVICES );            // GAP
    GATTServApp_AddService( GATT_ALL_SERVICES );    // GATT attributes
//    DevInfo_AddService();                           // Device Information Service
    #ifdef PHY_OTA_ENABLE
    ota_app_AddService();
    #endif
    GATTServApp_RegisterService( empty1_ProfileAttrTbl,
                                              GATT_NUM_ATTRS( empty1_ProfileAttrTbl ),
                                              NULL );
																							
    GATTServApp_RegisterService( empty2_ProfileAttrTbl,
                                              GATT_NUM_ATTRS( empty2_ProfileAttrTbl ),
                                              NULL );

    bleuart_AddService(on_bleuartServiceEvt);
   
//    GATTServApp_RegisterService( empty2_ProfileAttrTbl,
//                                              GATT_NUM_ATTRS( empty2_ProfileAttrTbl ),
//                                              NULL );
																							
    #if (1)
    {
        uint8_t mtuSet = 247;
        llInitFeatureSet2MPHY(TRUE);
        llInitFeatureSetDLE(TRUE);
        ATT_SetMTUSizeMax(mtuSet);
        LOG("[2Mbps | DLE | MTU %d] \n",mtuSet);
    }
    #else
    ATT_SetMTUSizeMax(23);
    llInitFeatureSet2MPHY(FALSE);
    llInitFeatureSetDLE(FALSE);
    #endif
    // Setup a delayed profile startup
    osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );
		
		hal_adc_init();
		osal_start_timerEx(simpleBLEPeripheral_TaskID, SBP_OSAL_EVT_ADC_TASK,2000);
    
}

/*********************************************************************
    @fn      SimpleBLEPeripheral_ProcessEvent

    @brief   Simple BLE Peripheral Application Task event processor.  This function
            is called to process all events for the task.  Events
            include timers, messages and any other user defined events.

    @param   task_id  - The OSAL assigned task ID.
    @param   events - events to process.  This is a bit map and can
                     contain more than one event.

    @return  events not processed
*/
uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
{
    VOID task_id; // OSAL required parameter that isn't used in this function

    if ( events & SYS_EVENT_MSG )
    {
        uint8* pMsg;

        if ( (pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )) != NULL )
        {
            // Release the OSAL message
            VOID osal_msg_deallocate( pMsg );
        }

        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
    }

    if ( events & SBP_START_DEVICE_EVT )
    {
        // Start the Device
        VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );
        #if(DEF_GAPBOND_MGR_ENABLE==1)
        // Start Bond Manager, 2017-11-15
        VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );
        #endif
        
        return ( events ^ SBP_START_DEVICE_EVT );
    }
		
		//enable notify
		if ( events & SBP_OSAL_EVT_NOTIFY_ENABLE )
    {
        set_Bleuart_Notify();
       
        return ( events ^ SBP_OSAL_EVT_NOTIFY_ENABLE );
    }
    //disable notify
    if ( events & SBP_OSAL_EVT_NOTIFY_DISABLE )
    {
        clear_Bleuart_Notify();
       
        return ( events ^ SBP_OSAL_EVT_NOTIFY_DISABLE );
    }

    //Connected 
    if ( events & SBP_OSAL_EVT_BLE_CONNECT )
    {
        
       
        return ( events ^ SBP_OSAL_EVT_BLE_CONNECT );
    }

    if ( events & SBP_OSAL_EVT_ADC_TASK )
    {
        adc_MeasureTask();
        return ( events ^ SBP_OSAL_EVT_ADC_TASK );
    }
    
   
    // Discard unknown events
    return 0;
}




/*********************************************************************
    @fn      peripheralStateReadRssiCB

    @brief   Notification from the profile of a state change.

    @param   newState - new state

    @return  none
*/
static void peripheralStateReadRssiCB( int8  rssi )
{
//    notifyBuf[15]++;
//    notifyBuf[16]=rssi;
//    notifyBuf[17]=HI_UINT16(g_conn_param_foff);
//    notifyBuf[18]=LO_UINT16(g_conn_param_foff);;
//    notifyBuf[19]=g_conn_param_carrSens;
}

/*********************************************************************
    @fn      peripheralStateNotificationCB

    @brief   Notification from the profile of a state change.

    @param   newState - new state

    @return  none
*/
static void peripheralStateNotificationCB( gaprole_States_t newState )
{
    switch ( newState )
    {
    case GAPROLE_STARTED:
    {
       
        
    }
    break;

    case GAPROLE_ADVERTISING:
    {
        
       
    }
    break;

    case GAPROLE_CONNECTED:
        GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle );
        osal_set_event( simpleBLEPeripheral_TaskID, SBP_OSAL_EVT_BLE_CONNECT );
        break;

    case GAPROLE_CONNECTED_ADV:
        break;

    case GAPROLE_WAITING:
        break;

    case GAPROLE_WAITING_AFTER_TIMEOUT:
        break;

    case GAPROLE_ERROR:
        break;

    default:
        break;
    }

    gapProfileState = newState;
    LOG("[GAP ROLE %d]\n",newState);
    VOID gapProfileState;
}





/*********************************************************************
*********************************************************************/
